# coding=utf-8
import random
from copy import copy

import pygame
from pygame.rect import Rect

from lib.Character import ProfessionType
from lib.Character.Hero import Hero
from lib.Core.Prims import Graph, dijkstra, shortest


class Room(object):
    def __init__(self, name, rect):
        super(Room, self).__init__()
        self.name = name
        self.rect = rect

    def start_point(self):
        pass

    def end_point(self):
        pass


class Player(object):
    def __init__(self, char, pos):
        super(Player, self).__init__()
        self.char = char
        self.pos = pos


class Camera(object):
    def __init__(self, point):
        super(Camera, self).__init__()
        self.point = point


def create_rects(room_num, room_width_area, room_height_area, max_x, max_y, block_size):
    rects = []
    for x in range(room_num):
        rect = create_rect(room_width_area, room_height_area, max_x, max_y, block_size)
        rects.append(rect)
    return rects


def in_rects(rects):
    for rect in rects:
        _rects = copy(rects)
        _rects.remove(rect)
        if not rect.collidelist(_rects) is -1:
            return True
    return False


def create_rect(room_width_area, room_height_area, max_x, max_y, block_size):
    width = int(random.randint(room_width_area[0], room_width_area[1]) / block_size[0]) * block_size[0]
    height = int(random.randint(room_height_area[0], room_height_area[1]) / block_size[1]) * block_size[1]
    x = random.randint(0, int(max_x / block_size[0])) * block_size[0]
    y = random.randint(0, int(max_y / block_size[1])) * block_size[1]
    return Rect(x, y, width, height)


def link_rooms(rects):
    g = Graph()
    for rect in rects:
        g.add_vertex(rect.center)

    for rect in rects:
        _rects = copy(rects)
        _rects.remove(rect)
        for z in _rects:
            frm = rect.center
            to = z.center
            v1 = pygame.math.Vector2(frm)
            v2 = pygame.math.Vector2(to)
            g.add_edge(frm, to, v1.distance_squared_to(v2))
    dijkstra(g, g.get_vertex(rects[1].center))

    last = []
    for t in rects:
        target = g.get_vertex(t.center)
        path = [t.center]
        shortest(target, path)
        last.append(path)
    return last


def main():
    # 人物
    char = Hero('name', ProfessionType.WARRIOR, 1, [])
    pos = 0, 0
    player = Player(char, pos)
    # 摄像机
    point = 0, 0
    camera = Camera(point)
    # 窗口大小
    width_scene = 1024
    height_scene = 600
    # 地图大小
    width_map = 10000
    height_map = 10000
    # 房间大小区间
    room_width_area = 800, 2000
    room_height_area = 800, 1200
    # 方块大小
    block_size = 32, 32
    # 房间数
    room_num = 8
    rooms = []

    max_x = width_map - room_width_area[1]
    max_y = height_map - room_height_area[1]

    rects = create_rects(room_num, room_width_area, room_height_area, max_x, max_y, block_size)
    in_rect = in_rects(rects)
    while in_rect:
        rects = create_rects(room_num, room_width_area, room_height_area, max_x, max_y, block_size)
        in_rect = in_rects(rects)

    # 所有房间
    for key, rect in enumerate(rects):
        rooms.append(Room('r_' + str(key), rect))

    # 起始房间与结束房间
    start_room = random.sample(rooms, 1)[0]
    _rooms = copy(rooms)
    _rooms.remove(start_room)
    end_room = random.sample(_rooms, 1)[0]

    # 创建起始点与结束点
    start_room.start_point()
    end_room.end_point()

    # 链接房间
    last = link_rooms(rects)

    group = pygame.sprite.Group()
    for rect in rects:
        sprite = pygame.sprite.Sprite()
        sprite.image = pygame.Surface(rect.size)
        r = random.randint(0, 255)
        g = random.randint(0, 255)
        b = random.randint(0, 255)
        sprite.image.fill([r, g, b])
        sprite.rect = rect
        group.add(sprite)

    pygame.init()
    display = pygame.display.set_mode([width_scene, height_scene])
    while True:
        for event in pygame.event.get():
            if event.type is pygame.QUIT:
                exit()
        group.draw(display)
        group.update()
        for pos in last:
            if len(pos) > 1:
                pygame.draw.line(display, [255, 255, 255], pos[0], pos[1], 1)
                # pass
        pygame.display.update()


if __name__ == '__main__':
    main()
